package com.trippin.servlets;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Date;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.trippin.DB.DBHandler;
import com.trippin.DB.entities.StickyNoteEntity;
import com.trippin.Utils.ServletUtil;
import com.trippin.Utils.ServletUtilConstants;

@SuppressWarnings("serial")
public class StickyNoteServlet extends HttpServlet {

	private static final Logger logger = Logger.getLogger(StickyNoteServlet.class.getCanonicalName());

	private static DBHandler dbHandlerInstance = DBHandler.INSTANCE;

	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		Action action = ServletUtil.getActionFromHeader(req,resp,StickyNoteServlet.class.toString());		
		long userId  = ServletUtil.getLongFromHeader(req, resp, ServletUtilConstants.USER_ID,
				StickyNoteServlet.class.toString(), action.getName());

		long stickyNoteId = -1;
		switch(action) {
		case GET_ALL_STICKY_NOTES_BY_STICKY_NOTE:
		case DELETE_STICKY_NOTE:
			stickyNoteId = ServletUtil.getLongFromHeader(req, resp, ServletUtilConstants.STICKY_NOTE_ID,
					NotificationServlet.class.toString(), action.getName());
			break;
		}

		try {
			String bodyResponse = "";
			switch(action) {
			case GET_STICKY_NOTES_BY_BOUND:
				bodyResponse = getStickyNoteByBound(userId,req,resp,action.getName());
				break;
			
			case CREATE_STICKY_NOTE:
				bodyResponse = createStickyNote(userId, req, resp, action.getName());
				break;
			
			case GET_ALL_USER_STICKY_NOTES:
				bodyResponse = getAllUserStickyNotes(userId);
				break;
			
			case GET_ALL_STICKY_NOTES_BY_STICKY_NOTE:
				bodyResponse = getAllStickyNotesByStickyNote(userId, stickyNoteId);
				break;
			
			case DELETE_STICKY_NOTE:
				bodyResponse = deletedUserStickyNote(userId, stickyNoteId);
				break;

			default:
				ServletUtil.printError(resp, action.getName(), StickyNoteServlet.class.getName(), ServletUtilConstants.ERROR_WRONG_ACTION_NAME);
				return;
			}

			ServletUtil.createResponse(resp, action.getName(), bodyResponse);


		} catch(Exception e) {
			ServletUtil.printError(resp,action.getName(), StickyNoteServlet.class.getName(), e.getMessage());
			logger.log(Level.SEVERE,e.toString(), e);
		}
	}

	private String deletedUserStickyNote(long userId, long stickyNoteId) throws IOException {
		Iterable<StickyNoteEntity> stickyNotes = dbHandlerInstance.deleteStickyNote(userId, stickyNoteId);
		return ServletUtil.getResponseBody(stickyNotes);
	}

	private String getAllStickyNotesByStickyNote(long userId, long stickyNoteId) throws IOException {
		Iterable<StickyNoteEntity> stickyNotes = dbHandlerInstance.getAllStickyNoteOfUserStickyNote(userId, stickyNoteId);
		return ServletUtil.getResponseBody(stickyNotes);
	}

	private String getAllUserStickyNotes(long userId) {
		Iterable<StickyNoteEntity> stickyNotes = dbHandlerInstance.getAllUserStickyNotes(userId);
		return ServletUtil.getResponseBody(stickyNotes);
	}

	private String getStickyNoteByBound(long userId, HttpServletRequest req,
			HttpServletResponse resp, String actionName) throws IOException {
		double latN = 0, latS = 0, lonE = 0, lonW = 0;
		try {
			latN = Double.parseDouble(req.getHeader(ServletUtilConstants.COORDINATES_LAT_N));
			latS = Double.parseDouble(req.getHeader(ServletUtilConstants.COORDINATES_LAT_S));
			lonE = Double.parseDouble(req.getHeader(ServletUtilConstants.COORDINATES_LON_E));
			lonW = Double.parseDouble(req.getHeader(ServletUtilConstants.COORDINATES_LON_W));
		} catch(Exception e){
			ServletUtil.printError(resp,actionName,StickyNoteServlet.class.getName(), ServletUtilConstants.ERROR_MISSING_COORDINATES);
		}

		Date startTime = ServletUtil.getDateTime(req,ServletUtilConstants.START_TIME);
		Date endTime = ServletUtil.getDateTime(req,ServletUtilConstants.END_TIME);

		Set<StickyNoteEntity> stickyNotes = 
				dbHandlerInstance.getStickyNotesByBound(userId, latN, lonE, latS, lonW,startTime, endTime);
		return ServletUtil.getResponseBody(stickyNotes);
	}
	
	private String createStickyNote(long userId, HttpServletRequest req,
			HttpServletResponse resp, String actionName) throws IOException {
		BufferedReader in = req.getReader();
		String reqBodyString = ServletUtil.getRequestBody(in);
		in.close();

		StickyNoteEntity stickyNote = (StickyNoteEntity)ServletUtil.getFromJSON(reqBodyString, StickyNoteEntity.class);		
		String[] requireds = {ServletUtilConstants.REQUIRED_LATITUDE, ServletUtilConstants.REQUIRED_LONGITUDE};
		ServletUtil.checkRequiredFields(reqBodyString,requireds, resp, actionName, StickyNoteServlet.class.getName());
		StickyNoteEntity stkNote = dbHandlerInstance.createStickyNote(userId, stickyNote);

		return ServletUtil.getResponseBody(stkNote);
	}

}
